﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace OnlineMealOrdering.Extends.Attributes
{
    /// <summary>
    /// This is filter attribute. It could filter request according to website's requirement for SSL.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
    public class SSLActionAttribute:ActionFilterAttribute
    {
        bool _isSSLRequired;
        bool _isAutoCovertToHttps;

        public SSLActionAttribute()
        {
            _isSSLRequired = true;
            _isAutoCovertToHttps = true;
        }

        public SSLActionAttribute(bool isSSLRequired)
        {
            _isSSLRequired = true;
            _isAutoCovertToHttps = true;
        }

        public SSLActionAttribute(bool isSSLRequired,bool isAutoCovertToHttps)
        {
            _isSSLRequired = isSSLRequired;
            _isAutoCovertToHttps = isAutoCovertToHttps;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //if (_isAutoCovertToHttps)
            //{
            //    filterContext.Result = GenHttpsActionResult(filterContext.HttpContext);
            //}

            if (_isSSLRequired)
            {
                if (!filterContext.HttpContext.Request.IsSecureConnection)
                {
                    filterContext.Result = new ContentResult()
                    {
                        Content = "该网站使用Https/SSL，请在访问地址前加https，例如https://ep.tinydeal.com",
                        ContentEncoding = Encoding.UTF8
                    };
                }
            }
            else
            {
                if (filterContext.HttpContext.Request.IsSecureConnection)
                {
                    filterContext.Result = new ContentResult()
                    {
                        Content = "该网站未使用Https/SSL，请在访问地址前不要加https，正确的地址格式类似http://ep.tinydeal.com",
                        ContentEncoding = Encoding.UTF8
                    };
                }
            }
        }

        protected virtual ActionResult GenSSLInvalidActionResult(HttpContextBase httpContext)
        {
            return new SSLInvalidResult();
        }

        /// <summary>
        /// 获取当前请求的url并将开头的http转换为https://
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        protected ActionResult GenHttpsActionResult(HttpContextBase httpContext)
        {
            var url = httpContext.Request.Url.AbsoluteUri.ToString();
            if (httpContext.Request.Url.Scheme.Equals("http", StringComparison.InvariantCultureIgnoreCase))
            {
                var builder = new UriBuilder(httpContext.Request.Url.AbsoluteUri);
                //将Scheme换成https
                builder.Scheme = "https";
                //这里需要将Port设置为-1,因为UriBuilder并没有创建新的uri,所以
                //如果从http过来的url在这里Port会保留80. 设置为-1时,ToString()
                //方法内会自动去掉":Port"的项
                builder.Port = -1;
                url = builder.ToString();
            }

            return new RedirectResult(url);
        }
    }

    /// <summary>
    /// Action result for request which is not SSL request when web site require SSL
    /// </summary>
    public class SSLInvalidResult : ActionResult
    {
        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            //SSL是403.4, SSL128是403.5
            context.HttpContext.Response.StatusCode = 403;
            context.HttpContext.Response.SubStatusCode = 4;
        }
    }
}
